#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
#include "fsl_debug_console.h"
#include "fsl_gpio.h"
#include "cmsis_os.h"
#include "fsl_lpuart.h"
#include "sal_module_wrapper.h"
#include "ec600s.h"
#include "tos_at.h"
#include "mqttclient.h"
#include "cjson.h"
#include "sal_module_wrapper.h"
#include "mcp2515.h"

#define USE_ESP8266
//#define USE_EC600S

#if defined(USE_ESP8266)
#include "esp8266.h"
#elif defined(USE_EC600S)
#include "ec600s.h"
#endif

#ifdef USE_ESP8266 
static hal_uart_port_t esp8266_port = HAL_UART_PORT_2;

void mqtt_set_esp8266_port(hal_uart_port_t port) {
    esp8266_port = port;
}
#endif

k_event_t report_result_event;
k_event_flag_t report_success = 1<<0;
k_event_flag_t report_fail    = 1<<1;

static void tos_topic_handler(void* client, message_data_t* msg)
{
    (void) client;
    cJSON* cjson_root   = NULL;
    cJSON* cjson_status = NULL;
    char* status = NULL;
    k_event_flag_t event_flag = report_fail;

    MQTT_LOG_I("-----------------------------------------------------------------------------------");
    MQTT_LOG_I("%s:%d %s()...\ntopic: %s, qos: %d. \nmessage:\n\t%s\n", __FILE__, __LINE__, __FUNCTION__, 
            msg->topic_name, msg->message->qos, (char*)msg->message->payload);
    MQTT_LOG_I("-----------------------------------------------------------------------------------\n");
    
    cjson_root = cJSON_Parse((char*)msg->message->payload);
    if (cjson_root == NULL) {
        printf("report reply message parser fail\r\n");
        event_flag = report_fail;
        goto exit;
    }
    
    cjson_status = cJSON_GetObjectItem(cjson_root, "status");
    status = cJSON_GetStringValue(cjson_status);
    if (cjson_status == NULL || status == NULL) {
        printf("report reply status parser fail\r\n");
        event_flag = report_fail;
        goto exit;
    }
    
    if (strstr(status,"success")) {
        event_flag = report_success;
    }else {
        event_flag = report_fail;
    }
    
exit:
    cJSON_Delete(cjson_root);
    cjson_root = NULL;
    status = NULL;
    
    tos_event_post(&report_result_event, event_flag);
    
    return;
}

#define REPORT_DATA_TEMPLATE "{\"method\":\"report\",\"clientToken\":\"00000002\",\"params\":{\"DATA1\":%d}}"
#define REPORT_DATA2_TEMPLATE "{\"method\":\"report\",\"clientToken\":\"00000002\",\"params\":{\"DATA2\":%d}}"
#define REPORT_DATA3_TEMPLATE "{\"method\":\"report\",\"clientToken\":\"00000002\",\"params\":{\"DATA3\":%d}}"
char report_buf[200];

void mqttclient_task(void)
{
    int error;
    
    int lightness = 0;
    int dat[10];
    
    mqtt_client_t *client = NULL;
    
    mqtt_message_t msg;
    
    k_event_flag_t match_flag;
    
    char  host_ip[20];
    
    memset(&msg, 0, sizeof(msg));
    
#ifdef USE_ESP8266 
    esp8266_sal_init(esp8266_port);
    //esp8266_join_ap("CU_VSVC", "iya8j5tt");
    esp8266_join_ap("TP-LINK_0F58", "hhyf1bhhyf1b");
#endif


#ifdef USE_EC600S
    ec600s_sal_init(HAL_UART_PORT_0);
#endif

    mqtt_log_init();

    client = mqtt_lease();
    
    tos_event_create(&report_result_event, (k_event_flag_t)0u);
    
    /* Domain Format: <your product ID>.iotcloud.tencentdevices.com */
    tos_sal_module_parse_domain("C161S8COPH.iotcloud.tencentdevices.com",host_ip,sizeof(host_ip));
    
    /*
        These infomation is generated by mqtt_config_gen.py tool in "TencentOS-tiny\tools" directory.
    */
    mqtt_set_port(client, "1883");
    mqtt_set_host(client, host_ip);

    mqtt_set_client_id(client, "C161S8COPHCAN_DEVICE");
    mqtt_set_user_name(client, "C161S8COPHCAN_DEVICE;12010126;6SFTL;1647175200");
    mqtt_set_password(client, "aa2a5bc2a3ba7c40959f7f07d925b402163424ea;hmacsha1");
    mqtt_set_clean_session(client, 1);

    error = mqtt_connect(client);
    
    //MQTT_LOG_D("mqtt connect error is %#0x", error);
    
    error = mqtt_subscribe(client, "$thing/down/property/C161S8COPH/CAN_DEVICE", QOS0, tos_topic_handler);
    
    //MQTT_LOG_D("mqtt subscribe error is %#0x", error);
    
    while (1) {
        memset(&msg, 0, sizeof(msg));
        
        //lightness=rxdat[0];
        dat[0]=rxdat[0];
        dat[1]=rxdat[1];
        dat[2]=rxdat[2];
        snprintf(report_buf, sizeof(report_buf), REPORT_DATA_TEMPLATE, dat[0]);

        msg.qos = QOS0;
        msg.payload = (void *) report_buf;
        
        error = mqtt_publish(client, "$thing/up/property/C161S8COPH/CAN_DEVICE", &msg);
        
        //MQTT_LOG_D("mqtt publish error is %#0x", error);

        snprintf(report_buf, sizeof(report_buf), REPORT_DATA2_TEMPLATE, dat[1]);
		msg.qos = QOS0;
		msg.payload = (void *) report_buf;
		error = mqtt_publish(client, "$thing/up/property/C161S8COPH/CAN_DEVICE", &msg);

		snprintf(report_buf, sizeof(report_buf), REPORT_DATA3_TEMPLATE, dat[2]);
		msg.qos = QOS0;
		msg.payload = (void *) report_buf;
		error = mqtt_publish(client, "$thing/up/property/C161S8COPH/CAN_DEVICE", &msg);

        
        tos_event_pend(&report_result_event, 
                       report_success|report_fail,
                       &match_flag,
                       TOS_TIME_FOREVER,
                       TOS_OPT_EVENT_PEND_ANY | TOS_OPT_EVENT_PEND_CLR);
        
        if (match_flag == report_success) {
            printf("report to Tencent IoT Explorer success\r\n");
        
        }else if (match_flag == report_fail){
            printf("report to Tencent IoT Explorer fail\r\n");
        }
        
        tos_task_delay(1000);
    }
}

void application_entry(void *arg)
{
    mqttclient_task();
    while (1) {
        printf("This is a mqtt demo!\r\n");
        tos_task_delay(1000);
    }
}
